﻿using System.Collections;
using System.Collections.Generic;

namespace SyncUdp.Model
{
    using SyncUdp.Event.NetworkEvent;
    using System;
    using UnityEngine;
    using UnityEngine.Windows;

    /// <summary>
    /// 用于 UDP 服务器存放帧数据的类
    /// </summary>
    public class UdpServerModel
    {
        int _curFrame;

        readonly int _maxPlayersCount;

        /// <summary>
        /// 每个客户端已经处理的帧数
        /// </summary>
        Dictionary<int, int> _clientHandledFramesDic;

        /// <summary>
        /// 每帧中有操作输入的客户端
        /// </summary>
        List<List<ClientInputsEvent>> _clientOptions;

        public int CurFrame 
        { 
            get => _curFrame;
            set
            {
                _curFrame = value;
            }
        }

        public List<ClientInputsEvent> AllOptionsOnCurFrame { get => _clientOptions[_curFrame]; }

        /// <summary>
        /// 构造器
        /// </summary>
        /// <param name="optionsCapacity">存放每帧操作的列表容量</param>
        public UdpServerModel(int optionsCapacity)
        {
            _curFrame = 0;
            //_maxPlayersCount = maxPlayersCount;
            _clientHandledFramesDic = new Dictionary<int, int>();
            _clientOptions = new List<List<ClientInputsEvent>>(optionsCapacity);
            for (int i = 0; i < optionsCapacity; i++)
                _clientOptions.Add(new List<ClientInputsEvent>(_maxPlayersCount));
        }

        public void AddClientOptions(ClientInputsEvent options)
        {
            // 更新客户端已处理的帧数
            _clientHandledFramesDic[options.id] = options.clientFrame;
            if (_curFrame == _clientOptions.Count)
                _clientOptions.Add(new List<ClientInputsEvent>());
            _clientOptions[_curFrame].Add(options);
        }

        public bool AddClient(int playerId)
        {
            return _clientHandledFramesDic.TryAdd(playerId, 0);
        }

        /// <summary>
        /// 获取从指定帧数到当前帧中的所有操作
        /// </summary>
        /// <param name="frame"></param>
        /// <returns></returns>
        public List<List<ClientInputsEvent>> GetInputsFromFrame2CurFrame(int frame)
        {
            // 最大 100 帧，余下部分下一帧补发；防止对方缓冲区不够
            int count = Math.Min(_curFrame - frame + 1, 50);
            return _clientOptions.GetRange(frame, count);
        }

        /// <summary>
        /// 获取某个客户端已处理的帧数
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public int GetClientHandledFrames(int clientId)
        {
            _clientHandledFramesDic.TryGetValue(clientId, out int frames);
            return frames;
        }
    }

}

